#include "../afwwin.h"
#include <gl/gl.h>

using namespace one_rag::detail;
using namespace one_rag;


Win32GLWindow::Win32GLWindow()
{
  _glrc=0;
  //ctor
}

Win32GLWindow::~Win32GLWindow()
{
  //dtor
}

LRESULT Win32GLWindow::WindowProc(UINT uMsg,WPARAM wParam ,LPARAM lParam)
{
  switch(uMsg){
      HDC hdc;
      PAINTSTRUCT ps;
      int w,h;
    case WM_SIZE:
      w = LOWORD(lParam);
      h = HIWORD(lParam);
      if(w && h)
      {
        hdc = GetDC(_wnd);
        wglMakeCurrent(hdc,_glrc);
       	glViewport(0, 0, w, h);
       	if(_delegate)
       	  _delegate->OnReshape(w,h);
       	wglMakeCurrent(hdc,NULL);
       	/*
          glMatrixMode(GL_PROJECTION) indicates that the next 2 lines of code will affect the projection matrix. The projection matrix is responsible for adding perspective to our scene. glLoadIdentity() is similar to a reset. It restores the selected matrix to it's original state. After glLoadIdentity() has been called we set up our perspective view for the scene. glMatrixMode(GL_MODELVIEW) indicates that any new transformations will affect the modelview matrix. The modelview matrix is where our object information is stored. Lastly we reset the modelview matrix. Don't worry if you don't understand this stuff, I will be explaining it all in later tutorials. Just know that it HAS to be done if you want a nice perspective scene.
	        glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix
	        glLoadIdentity();							// Reset The Projection Matrix
          // Calculate The Aspect Ratio Of The Window
	        gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
          glMatrixMode(GL_MODELVIEW);						// Select The Modelview Matrix
	        glLoadIdentity();							// Reset The Modelview Matrix
	        */
      }
      break;
    case WM_PAINT:
      hdc = BeginPaint(_wnd,&ps);
      wglMakeCurrent(hdc,_glrc);
      if(_delegate)
        _delegate->OnDisplay();
      SwapBuffers(hdc);
      wglMakeCurrent(hdc,_glrc);
      EndPaint(_wnd,&ps);
      return 0;
    case WM_TIMER:
      if(_delegate)
        _delegate->OnTimer();
      break;
    case WM_DESTROY:
      DisableOpenGL();
      break;
  }

   return View::WindowProc(uMsg,wParam,lParam);
}

HWND Win32GLWindow::Create(Window& parent,int x,int y,int w,int h)
{
  ATOM atm = RegisterClass(TEXT("AFWGLVIEW"));
  HWND ret;
  if( (ret = Window::Create(parent,atm,x,y,w,h)))
    EnableOpenGL();
  return ret;
}


void Win32GLWindow::EnableOpenGL()
{
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    /* get the device context (DC) */
    HDC hDC = GetDC(_wnd);

    /* set the pixel format for the DC */
    ZeroMemory(&pfd, sizeof(pfd));

    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;

    iFormat = ChoosePixelFormat(hDC, &pfd);

    SetPixelFormat(hDC, iFormat, &pfd);

    /* create and enable the render context (RC) */
    _glrc = wglCreateContext(hDC);

//    wglMakeCurrent(hDC, *hRC);
    ReleaseDC(_wnd, hDC);
}

void Win32GLWindow::DisableOpenGL()
{
//    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(_glrc);
    //ReleaseDC(hwnd, hDC);
}

void Win32GLWindow::PostRedisplay()
{
  InvalidateRect(_wnd,NULL,FALSE);
}

